package com.ztom.v2;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * @author ZhangTao
 */
public class Code07TrappingRainWater {

    public int trap(int[] height) {
        int res = 0;
        Deque<Integer> stack = new ArrayDeque<>();
        for (int i = 0; i < height.length; i++) {
            // 单调栈找到左右两边离自己最近的比自己大的值, 计算二者围成的矩形
            while (!stack.isEmpty() && height[stack.peekLast()] < height[i]) {
                Integer cur = stack.pollLast();
                // 左边没有, 无法盛放雨水
                if (stack.isEmpty()) {
                    break;
                }
                int l = stack.peekLast();
                int r = i;
                int width = r - l - 1;
                int high = Math.min(height[l], height[r]) - height[cur];
                res += width * high;
            }
            stack.addLast(i);
        }
        // 栈里剩下的都是最大值, 无法盛放雨水, 忽略
        return res;
    }

    public int trap2(int[] height) {
        int res = 0;
        // 双指针优化
        int l = 0;
        int r = height.length - 1;
        int lMax = 0;
        int rMax = 0;
        while (l < r) {
            lMax = Math.max(lMax, height[l]);
            rMax = Math.max(rMax, height[r]);
            if (height[l] < height[r]) {
                res += lMax - height[l];
                l++;
            } else {
                res += rMax - height[r];
                r--;
            }
        }
        return res;
    }
}
